<template>
  <div class="meeting-reserve-container">
    <div class="meeting-reserve-left">
      <CalendarViewSelect
        v-model="currentDate"
        :legend-items="legendItems"
        :dot-calculator="scheduleDotCalculator"
        @month-change="getMonthData"
        @change="handleDayClick"
      />
    </div>

    <div class="meeting-reserve-right">
      <ContentWrap>
        <!-- 搜索工作栏 -->
        <el-form
          class="-mb-15px"
          :model="queryParams"
          ref="queryFormRef"
          :inline="true"
          label-width="68px"
        >
          <el-form-item label="会议主题" prop="title">
            <el-input
              v-model="queryParams.title"
              placeholder="请输入会议主题"
              clearable
              @keyup.enter="handleQuery"
              class="!w-240px"
            />
          </el-form-item>

          <!-- <el-form-item label="状态" prop="status" width="80px">
            <el-select
              v-model="queryParams.status"
              placeholder="请选择状态"
              clearable
              class="!w-240px"
            >
              <el-option
                v-for="dict in getDictLabel(DICT_TYPE.SCHOOL_MEETING_RESERVE_STATUS)"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item> -->
          <el-form-item>
            <el-button @click="handleQuery"
              ><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button
            >
            <el-button @click="resetQuery"
              ><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button
            >
            <el-button
              type="primary"
              plain
              @click="openForm('create')"
              v-hasPermi="['school:meeting-reserve:create']"
            >
              <Icon icon="ep:plus" class="mr-5px" /> 新增
            </el-button>
            <!-- <el-button
              type="success"
              plain
              @click="handleExport"
              :loading="exportLoading"
              v-hasPermi="['school:meeting-reserve:export']"
            >
              <Icon icon="ep:download" class="mr-5px" /> 导出
            </el-button> -->
          </el-form-item>
        </el-form>
      </ContentWrap>

      <!-- 列表 -->
      <ContentWrap class="!mb-0">
        <!-- Tabs切换 -->
        <el-tabs class="mt--10px" v-model="activeTab" @tab-change="handleTabChange">
          <el-tab-pane label="会议预约" name="reserve" />
          <el-tab-pane label="所有会议" name="all" />
        </el-tabs>
        <!-- 卡片列表 -->
        <div class="card-list">
          <template v-if="filteredList.length">
            <div v-for="(item, index) in filteredList" :key="index" class="schedule-card">
              <div class="text-18px text-#333"
                ><div class="inline-block w-80px text-right">园区：</div>
                {{ getDictLabel(DICT_TYPE.SCHOOL_CODE, item.schoolCode) }}</div
              >
              <div class=""
                ><div class="inline-block w-80px text-right">会议室：</div>{{ item.roomName }}</div
              >
              <div class=""
                ><div class="inline-block w-80px text-right">会议主题：</div>{{ item.title }}</div
              >
              <div class=""
                ><div class="inline-block w-80px text-right">预约人：</div>{{ item.userName }}</div
              >
              <div class="flex"
                ><span class="flex-shrink-0 inline-block w-80px text-right">参会人员：</span>
                <span
                  ><span
                    class="m-r-10px ws-nowrap"
                    v-for="(user, userIndex) in item.userNames"
                    :key="userIndex"
                  >
                    {{ user }}
                  </span></span
                >
              </div>
              <div class=""
                ><div class="inline-block w-80px text-right">开始时间：</div
                >{{ formatDate(item.startTime) }}</div
              >
              <div class=""
                ><div class="inline-block w-80px text-right">结束时间：</div
                >{{ formatDate(item.endTime) }}</div
              >
              <div class=""
                ><div class="inline-block w-80px text-right">会议时长：</div
                >{{ `${item.duration ? item.duration + '分钟' : '-'}` }}</div
              >
              <div class=""
                ><div class="inline-block w-80px text-right">会议文件：</div
                ><FileListView :file-list="item.fileUrls"
              /></div>
              <div
                class=""
                :data="
                  item.statusObj = getDictObj(DICT_TYPE.SCHOOL_MEETING_RESERVE_STATUS, item.status)
                "
                ><div class="inline-block w-80px text-right">状态：</div
                ><span :class="[{ 'text-#14D10A': item.statusObj.value === '0' }]">{{
                  item.statusObj.label
                }}</span></div
              >
              <div class="flex justify-end items-baseline mt--9px">
                <!-- <div class="m-r-18px">创建时间：{{ formatDate(item.createTime) }}</div> -->
                <el-button
                  v-if="item.userIds.includes(userStore.user.id) && item.isApprove === 0"
                  link
                  type="success"
                  @click="handleApprove(item)"
                  v-hasPermi="['school:meeting-reserve:approve']"
                >
                  审核
                </el-button>
                <el-button
                  class="!m-l-6px"
                  link
                  type="primary"
                  @click="openForm('update', item.id)"
                  v-hasPermi="['school:meeting-reserve:update']"
                >
                  编辑
                </el-button>
                <!-- 创建人等于当前用户， 才有取消权限 -->
                <el-button
                  v-if="item.userName === userStore.user.nickname"
                  class="!m-l-6px"
                  link
                  type="warning"
                  @click="handleCancel(item.id)"
                  v-hasPermi="['school:meeting-reserve:cancel']"
                >
                  取消
                </el-button>
              </div>
            </div>
          </template>
          <template v-else>
            <el-empty v-if="!loading" description="暂无会议" />
          </template>
        </div>

        <!-- 无数据状态 -->
      </ContentWrap>
    </div>
  </div>

  <!-- 表单弹窗：添加/修改 -->
  <MeetingReserveForm ref="formRef" @success="handleFormSuccess" />
</template>

<script setup lang="ts">
import type { CalendarDateType, CalendarInstance } from 'element-plus'
import { getDictLabel, getDictObj, DICT_TYPE } from '@/utils/dict'
import { dateFormatter, formatDate } from '@/utils/formatTime'
import download from '@/utils/download'
import { MeetingReserveApi, MeetingReserveVO } from '@/api/school/meeting/reserve'
import MeetingReserveForm from './MeetingReserveForm.vue'
import { useUserStore } from '@/store/modules/user'
import { ElMessageBox } from 'element-plus'
import { LegendItem, CalendarDot } from '@/components/CalendarViewSelect/index.vue'
/** 会议室预约 列表 */
defineOptions({ name: 'SchoolMeetingReserve' })

const { query } = useRoute()
const userStore = useUserStore()
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化

const currentDate: any = ref(new Date()) // 当前选中的日期
const selectedDate = ref(formatDate(new Date(), 'YYYY-MM-DD')) // 选中的日期字符串
const monthData = ref<Record<string, any>>({}) // 月份数据，记录每天的会议预约情况
const oldMonth = ref('') // 上一次查询的月份

const activeTab = ref('reserve') // Tabs默认选中项
const loading = ref(true) // 列表的加载中
const list = ref<MeetingReserveVO[]>([]) // 列表的数据
const queryParams: any = reactive({
  title: undefined,
  schoolCode: undefined,
  roomId: undefined,
  status: undefined
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
// 定义图例项
const legendItems: LegendItem[] = [
  {
    style: { backgroundColor: '#f56c6c', width: '6px' },
    text: '我的预约'
  },
  {
    style: { backgroundColor: '#67c23a', width: '6px' },
    text: '我的会议'
  }
]
/** 根据Tabs选项筛选列表 */
const filteredList: any = computed(() => {
  // 先根据搜索条件过滤
  let result = list.value

  // 根据主题搜索
  if (queryParams.title) {
    result = result.filter((item) => item.title.includes(queryParams.title!))
  }

  // 根据Tabs选项筛选
  if (activeTab.value === 'reserve') {
    // 会议预约 tab 显示状态为 0(正常) 和 1(未审核) 的数据
    result = result.filter((item) => item.status === 1 || item.status === 2)
  } else if (activeTab.value === 'all') {
    // 所有会议 tab 显示状态为 2(审核未通过) 的数据
    result = result.filter((item) => item.status === 0)
  }

  return result
})

/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    // 使用 getMeetingReserveByDay 接口，按选定日期查询
    const data = await MeetingReserveApi.getMeetingReserveByDay(
      selectedDate.value.replace(/-/g, '')
    )
    list.value = data || []
  } finally {
    loading.value = false
  }
}

/** 获取指定月份的会议预约数据 */
const getMonthData = async (month: string) => {
  oldMonth.value = month
  try {
    const data = await MeetingReserveApi.getMeetingReserveByMonth(month)
    monthData.value = {}
    data?.forEach((item: any) => {
      // 将日期格式化为 YYYYMMDD 格式作为 key
      const key = item.day
      monthData.value[key] = {
        isHasMyReserve: item.isHasMyReserve,
        isHasMyMeeting: item.isHasMyMeeting
      }
    })
  } catch (error) {
    console.error('获取月份会议预约数据失败:', error)
  }
}

/** 获取指定日期的会议预约 */
const getDayMeetingReserve = async (day: string) => {
  // 更新查询参数中的日期
  queryParams.day = day
  // 重置分页
  queryParams.pageNo = 1
  // 查询该日期的会议预约
  await getList()
}

/** 处理日期选择 */
const handleDaySelect = (value: Date) => {
  const dateStr = formatDate(value, 'YYYY-MM-DD')
  selectedDate.value = dateStr
  getDayMeetingReserve(dateStr)
}

/** 处理日期点击 */
const handleDayClick = (data: any) => {
  const date = new Date(data.day)
  handleDaySelect(date)
}
// 定义日程点计算器
const scheduleDotCalculator = (day: string): CalendarDot[] => {
  const key = day.replace(/-/g, '')
  const status = monthData.value?.[key]
  const dotArray: CalendarDot[] = []

  if (!status) return dotArray

  // 我的预约 - 红色点
  if (status.isHasMyReserve) {
    dotArray.push(legendItems[0])
  }

  // 我的会议 - 绿色点
  if (status.isHasMyMeeting) {
    dotArray.push(legendItems[1])
  }

  return dotArray
}

/** Tabs切换 */
const handleTabChange = () => {
  // Tab切换时不需要重新请求数据，只需重新计算filteredList
}

/** 搜索按钮操作 */
const handleQuery = () => {
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
  formRef.value.open(type, id)
}
const approveMeetingReserve = async (id, status) => {
  try {
    const res = await MeetingReserveApi.approveMeetingReserve({
      id,
      status
    })
    if (res) {
      message.success('审核完成')
      await getList()
    }
  } catch (e) {
    message.error((e as string) || '审核失败')
  }
}
const handleApprove = async (item: any) => {
  try {
    const action = await ElMessageBox.confirm(item.title, '审核', {
      distinguishCancelAndClose: true,
      confirmButtonText: '通过',
      cancelButtonText: '拒绝',
      type: 'primary'
    })
    if (action === 'confirm') {
      // 发起删除
      approveMeetingReserve(item.id, 0)
    }
  } catch (action) {
    console.log('取消操作2', action)

    if (action === 'cancel') {
      approveMeetingReserve(item.id, 2)
    }
  }
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await MeetingReserveApi.deleteMeetingReserve(id)
    message.success(t('common.delSuccess'))
    // 刷新列表
    await getList()
  } catch {}
}

/** 取消按钮操作 */
const handleCancel = async (id: number) => {
  try {
    // 二次确认
    await message.confirm(`确定取消当前会议吗？`)
    // 发起删除
    await MeetingReserveApi.cancelMeetingReserve(id)
    message.success(t('common.success'))
    // 刷新列表
    await getList()
  } catch {}
}

/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await MeetingReserveApi.exportMeetingReserve(queryParams)
    download.excel(data, '会议室预约.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

/** 表单操作成功回调 */
const handleFormSuccess = async () => {
  // 重新获取当前月份数据以更新日历上的点
  const month = formatDate(currentDate.value, 'YYYYMM')
  await getMonthData(month)
  // 刷新列表
  await getList()
}

/** 监听日期变化 */
watch(currentDate, (val) => {
  const month = formatDate(val, 'YYYYMM')
  const day = formatDate(val, 'YYYY-MM-DD')

  // 如果月份变化了，重新获取月份数据
  if (oldMonth.value !== month) {
    getMonthData(month)
  }
  if (day) {
    handleDayClick({ day })
  }
})
watch(
  () => query.dayDate,
  (dayDate) => {
    const isUpdate = dayDate === currentDate.value
    if (dayDate) {
      currentDate.value = dayDate
    }
    if (isUpdate || !dayDate) {
      // 获取当前月份数据
      const month = formatDate(currentDate.value, 'YYYYMM')
      getMonthData(month)
      // 获取当前日期的会议预约
      handleDayClick({ day: currentDate.value })
    }
  },
  {
    immediate: true
  }
)
</script>

<style lang="scss" scoped>
.meeting-reserve-container {
  display: flex;
  column-gap: 20px;
  min-height: $content-height;
}

.meeting-reserve-left {
  width: 350px;
  padding: 15px;
  background-color: #fff;
  flex-shrink: 0;

  .legend {
    padding: 12px;
    margin-top: 12px;
    font-size: 14px;
    color: #606266;
    text-align: center;

    .legend-item {
      display: inline-flex;
      align-items: center;
      gap: 4px;
      margin-right: 12px;

      &:last-child {
        margin-right: 0;
      }
    }
  }
}

.meeting-reserve-right {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.card-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  height: calc($content-height - 138px);
  overflow-y: auto; /* 启用垂直滚动 */

  .schedule-card {
    position: relative;
    padding: 15px 15px 9px;
    line-height: 24px;
    color: #666;
    background-color: var(--card-bg-color);
    border-left: 2.1px solid var(--card-border-color);
    border-radius: 4px;

    &:nth-child(6n + 1) {
      --card-bg-color: #fff2f2;
      --card-border-color: #ff6969;
    }

    &:nth-child(6n + 2) {
      --card-bg-color: #fff6ed;
      --card-border-color: #ffa978;
    }

    &:nth-child(6n + 3) {
      --card-bg-color: #f2fff2;
      --card-border-color: #6eff6e;
    }

    &:nth-child(6n + 4) {
      --card-bg-color: #f0ffff;
      --card-border-color: #82fffd;
    }

    &:nth-child(6n + 5) {
      --card-bg-color: #edf3ff;
      --card-border-color: #8f9eff;
    }

    &:nth-child(6n + 6) {
      --card-bg-color: #fff0ff;
      --card-border-color: #ff54fc;
    }
  }

  :deep() {
    .view-button {
      font-size: 16px;
      font-weight: 400;
    }
  }
}
</style>
